package com.lik.littleworld.web.handler;

import com.lik.littleworld.common.BaseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;

/**
 * @author lik
 * 全局异常处理器
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {


    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public BaseResult error(Exception e){
        String message = e.getMessage();
        e.printStackTrace();
        log.error(message);
        return BaseResult.fail(message);
    }

    /*  数据校验处理 */
    @ResponseBody
    @ExceptionHandler({BindException.class, ConstraintViolationException.class})
    public BaseResult validatorExceptionHandler(Exception e) {
        String msg = e instanceof BindException ? msgConvertor(((BindException) e).getBindingResult())
                : msgConvertor(((ConstraintViolationException) e).getConstraintViolations());
        log.warn(msg);
        return BaseResult.fail(msg);
    }

    @ResponseBody
    @ExceptionHandler({ MethodArgumentNotValidException.class})
    public BaseResult methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException ex){
        String message = msgConvertor(ex.getBindingResult());
        log.warn(message);
        return BaseResult.fail(message);
    }

    /**
     * 校验消息转换拼接
     *
     * @param bindingResult
     * @return
     */
    public static String msgConvertor(BindingResult bindingResult) {
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        StringBuilder sb = new StringBuilder();
        fieldErrors.forEach(fieldError -> sb.append(fieldError.getDefaultMessage()).append(","));

        return sb.deleteCharAt(sb.length() - 1).toString().toLowerCase();
    }

    private String msgConvertor(Set<ConstraintViolation<?>> constraintViolations) {
        StringBuilder sb = new StringBuilder();
        constraintViolations.forEach(violation -> sb.append(violation.getMessage()).append(","));

        return sb.deleteCharAt(sb.length() - 1).toString();
    }

}
